package com.polaris.live.common.network

import com.blankj.utilcode.util.EncodeUtils
import com.polaris.live.common.constant.ServerConfig
import com.polaris.live.common.constant.TestServerMode
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec

/**
 * AES加解密
 *
 * @author Created by 半仙 on 2023/7/31/031 16:44
 */
object EncryptHelper {

    private const val AES_TYPE = "AES/CBC/PKCS5Padding"
    private const val IV = "O6xlNQ4e5oRTVZSu"

    /**
     * AES加密
     *
     */
    fun encryptParams(params: String, iv: String = IV): String {
        val bytes = encryptBase64(ServerConfig.getServerMode().encrypt, params, iv)
        return String(EncodeUtils.base64Encode(bytes))
    }

    private fun encryptBase64(secretKey: String, plainText: String, iv: String = IV): ByteArray? {
        if (plainText.isBlank()) {
            return null
        }

        return encrypt(secretKey, EncodeUtils.base64Encode(plainText), iv)
    }

    private fun encrypt(secretKey: String, bytes: ByteArray, iv: String = IV): ByteArray? {
        if (secretKey.isBlank() || bytes.isEmpty()) {
            return null
        }

        return try {
            Cipher.getInstance(AES_TYPE)
                .run {
                    val key = SecretKeySpec(secretKey.toByteArray(), "AES")
                    val ivParameterSpec = IvParameterSpec(iv.toByteArray(Charsets.UTF_8))
                    init(Cipher.ENCRYPT_MODE, key, ivParameterSpec)
                    doFinal(bytes)
                }
        } catch (e: Exception) {
            e.printStackTrace()
            return null
        }
    }

    fun decryptParams(input: String, iv: String = IV): String? {
        return decrypt(input, ServerConfig.getServerMode().encrypt, iv)
    }

    fun decrypt(input: String, key: String, iv: String = IV): String? {
        return try {
            Cipher.getInstance(AES_TYPE)
                .run {
                    val tempInput = EncodeUtils.base64Decode(input)

                    val password = SecretKeySpec(key.toByteArray(), "AES")
                    val ivParameterSpec = IvParameterSpec(iv.toByteArray(Charsets.UTF_8))
                    init(Cipher.DECRYPT_MODE, password, ivParameterSpec)

                    val requestInput = EncodeUtils.base64Decode(doFinal(tempInput))
                    String(requestInput)
                }
        } catch (e: Exception) {
            e.printStackTrace()
            return null
        }
    }
}

fun readEncryptKey1(key: String): String {
    val param = EncryptHelper.decrypt(key, TestServerMode.encrypt) ?: return ""

    return String(EncodeUtils.base64Decode(param)).let {
        it.substring(0, it.length - TestServerMode.secEncrypt.length)
    }
}

fun readEncryptKey2(key: String): String {
    val param = EncryptHelper.decrypt(key, TestServerMode.secEncrypt) ?: return ""

    return String(EncodeUtils.base64Decode(param)).substring(TestServerMode.encrypt.length)
}